/**
 * HTML 内容过滤方法
 */

/**
 * 格式化 HTML 内容
 * 
 * @removes 需要移除的 HTML 标签，数组类型如 ["br","label"]
 */
function htmlfilter( val, removes )
{
	// 去除指定的标签
	var remove_tag = "";
	if( !empty( removes ) && removes.length && removes.length > 0 )
	{
		remove_tag = removes.join( "|" );
		var reg = new RegExp( "<\/?(" + remove_tag + ")([^>]*)>", "ig" );
		val = val.replace( reg, "" );
	}

	// 保留表格
	val = encode_table( val );

	// 尝试保留一些属性值
	var tags = val.match( /<[^>]*>/ig );
	if( !empty( tags ) && tags.length && tags.length > 0 )
	{
		for( var i = 0; i < tags.length; i++ )
		{
			val = val.replace( tags[ i ], replace_tag( tags[ i ], "style:color,font-size|href:*|target:*|rel:*|id:*" ) );
		}
	}
	val = val.replace( /<(\/?)(ul|li|br|div|span|strong|b|u|i|p|a)([^>]*)>/ig, "「$1$2」" );

	// 去除 html 标签
	val = val.replace( /<[^>]*>/ig, "" );

	// 还原保留的标签
	val = val.replace( /\n{2,}/g, "" );
	val = val.replace( /「([^」]+)」/ig, "<$1>" );

	// 还原表格
	val = decode_table( val );

	// 去除空标签
	val = val.replace( /\n/g, "" );
	val = val.replace( /\r/g, "<br/>" );

	return val;
}

/**
 * 替换指定标签，保留指定属性的某些值
 * 
 * @param html html标签
 * @param attrs 如style属性的"color，font-size"样式，参数值写成 "style:color,font-size"
 */
function replace_tag( html, attrs )
{
	var as = parse_attrs( attrs );

	// 直接去除所有属性的标签列表
	var remove_list = [ "br" ];

	// 标签的所有属性集合
	var p_attr = html.match( /\w+="([^"]+)"/ig );

	// 标签名
	var tag = html.replace( /<(\w+)\s*[^>]+>/i, "$1" );

	// 属性列表
	var attr_table = [];

	// 解析保留属性
	var size = empty( p_attr ) ? 0 : p_attr.length;

	if( size > 0 )
	{
		if( remove_list.indexOf( tag ) != -1 )
		{
			// 直接去除所有属性
			html = "「" + tag + "」";
		}
		else
		{
			for( var i = 0; i < size; i++ )
			{
				// 分解属性名称和值
				var p_attr_cut = p_attr[ i ].split( "=" );

				// 当前属性需要保留的值表
				var p_val_list = [];

				// 允许保留该属性及哪些值
				var set = get_tag_set( as, p_attr_cut[ 0 ] );//["color","font-size"]

				if( set != null )
				{
					// 分解属性中的子属性
					var val_list = p_attr_cut[ 1 ].replace( /^"/, "" );
					val_list = val_list.replace( /"$/, "" );
					var c_attr = val_list.split( ";" );

					for( var j = 0; j < c_attr.length; j++ )
					{
						// 分解子属性的名称和值
						var c_attr_cut = c_attr[ j ].split( /\s*:\s*/i );

						if( set.indexOf( c_attr_cut[ 0 ] ) != -1 || set.indexOf( "*" ) != -1 )
						{
							p_val_list.push( c_attr[ j ] );
						}
					}
				}

				if( p_val_list.length > 0 )
				{
					attr_table.push( p_attr_cut[ 0 ] + "=\"" + p_val_list.join( ";" ) + "\"" );
				}
			}

			var at = attr_table.length > 0 ? " " : "";
			at += attr_table.join( " " );
			html = "「" + tag + at + "」";
		}
	}
	else
	{
	}

	return html;
}

/**
 * 根据指定属性名，尝试从集合中取得定义
 * 
 * @param set 允许保留的属性集合
 * @param attr 指定要获取的属性名称
 */
function get_tag_set( set, attr )
{
	return empty( set[ attr ] ) ? null : set[ attr ];
}

/**
 * 分析属性表
 * 
 * @param attrs 如 "style:color,font-size"
 * @return {style:["color","font-size"]}
 */
function parse_attrs( attrs )
{
	var info_table = attrs.split( "|" );
	var r = {};

	for( var i = 0; i < info_table.length; i++ )
	{
		var t = info_table[ i ].split( ":" );// ["style","color,font-size"]

		if( t[ 1 ] == "*" )
		{
			r[ t[ 0 ] ] = "*";
		}
		else
		{
			r[ t[ 0 ] ] = t[ 1 ].split( "," );// ["color","font-size"]
		}
	}
	return r;
}

/**
 * 将HTML中包含的表格代码编码
 */
function encode_table( val )
{
	// 去除 tbody 标签
	val = val.replace( /<\/?tbody>/ig, "" );
	val = val.replace( /<(table|tr|th|td)(\s\w+="[^"]*"\s*)*(\sclass="[^"]*"\s*)*(\s\w+="[^"]*"\s*)*>/ig,
			"<$1$2$4>" );
	val = val.replace( /<(\/?)(table|tr|th|td)([^>]*)>/ig, "「$1$2$3」" );

	return val;
}

/**
 * 解码经编码后的HTML内容
 * 
 * @param val
 */
function decode_table( val )
{
	val = val.replace( /「(\/?)(table|tr|th|td)([^」]*)」/ig, "<$1$2$3>" );
	return val;
}
